package com.wtwd.campus.receiver;

import com.wtwd.campus.common.Constants;
import com.wtwd.campus.encryptnetty.EncryptChannelMap;
import com.wtwd.campus.entity.Command;
import com.wtwd.campus.entity.MqHeartBeatMessage;
import com.wtwd.campus.entity.MqLocationData;
import com.wtwd.campus.netty.ChannelMap;
import com.wtwd.campus.service.InjectFeignService;
import com.wtwd.campus.service.WebRemoteService;
import com.wtwd.campus.service.entity.DeviceInfo;
import com.wtwd.campus.utils.InjectService;
import com.wtwd.campus.utils.LocationUtils;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Component
public class UploadLocateHeartReceiver implements Receiver {

    // 接收数据的统计
    public static Map<String, AtomicInteger> receiveCount = new ConcurrentHashMap<>();

    private Logger log = LoggerFactory.getLogger("newAppender");


    @Override
    public String parseMessage(String data) {
        //*WT,800115470000876,V2,170652,108,0,8,0,A,2250.2261,N,11391.6159,E,0.11,356,030621,FFFFDFFF#
        //分割字符串获取指令信息
        WebRemoteService webRemoteService = InjectFeignService.getWebRemoteService();
        String[] split = data.split(",");
        String imei = split[1];
        String messageType = split[2];
        String commandNumber = split[3];
        String gsm = split[4];//gsm
        String gps = split[5];//gps
        String battery = split[6];//电量
        String stepNum = split[7];  // 步数
        String lat = split[9];
        String lng = split[11];
        String speed = split[13];
        String orientation = split[14];
        String date = split[15];
        String deviceStatus = split[16];
        DeviceInfo deviceInfo = webRemoteService.queryDeviceInfoByImei(imei);
        Boolean isOriData = false;
        if (deviceInfo != null) {
            if (Constants.YPT_A6_ORG_CODE.equals(deviceInfo.getOrgCode())){
                isOriData=true;
            }
        }
        List<Double> list = LocationUtils.DFToLatLng(lng,lat,isOriData);
        MqHeartBeatMessage mqHeartBeatMessage = new MqHeartBeatMessage();
        mqHeartBeatMessage.setImei(imei);
        mqHeartBeatMessage.setCommandNumber(commandNumber);
        mqHeartBeatMessage.setBattery(Integer.parseInt(battery));
        mqHeartBeatMessage.setDeviceDate(date);
        mqHeartBeatMessage.setDeviceTime(commandNumber);
        mqHeartBeatMessage.setStepNum(Integer.parseInt(stepNum));
        mqHeartBeatMessage.setDeviceStatus(deviceStatus);
        MqLocationData mqLocationData = new MqLocationData();
        mqLocationData.setOrientation(Integer.parseInt(orientation));
        mqLocationData.setSpeed(Double.parseDouble(speed));
        mqLocationData.setLatitude(list.get(1));
        mqLocationData.setLongitude(list.get(0));
        mqHeartBeatMessage.setMqLocationData(mqLocationData);
        InjectFeignService.getIrmFeignClientService().upHeartBeatMessage(mqHeartBeatMessage);
        //用于保存因发送失败次数超过规定次数的指令的序列号
        List<String> failSendList = new ArrayList<>();
        //从redis中查询出该设备所有的未回复的指令，再次进行发送
        Integer isEncrypted = InjectService.deviceIsEncrypt(imei);
        if (isEncrypted == null) {
            return imei;
        }
        Channel channel = isEncrypted == 1 ? ChannelMap.get(imei) : EncryptChannelMap.get(imei);
        if (channel != null) {
            Map<String, Object> commands = InjectService.getCommands(imei);
            if (commands != null && !commands.isEmpty()) {
                for (Map.Entry<String, Object> entry : commands.entrySet()) {
                    Command command = (Command) entry.getValue();
                    if (command.getRepeatCount() != null && command.getRepeatCount() == 2) {
                        //重发两次就算失败
                        String result = entry.getKey();
                        failSendList.add(result);
                    } else {
                        // 解决部分null 或者之前为null的情况
                        Long lastSendTime = command.getLastSendTime() == null ? 0 : command.getLastSendTime();
                        // 上次发送超过15s的才重发
                        if (System.currentTimeMillis() - lastSendTime > 15 * 1000L) {
                            channel.writeAndFlush(command.getContent());
                            log.info("重新下发指令：" + command.getContent());
                            command.setLastSendTime(System.currentTimeMillis());
                            command.setRepeatCount(command.getRepeatCount() == null ? 1 : command.getRepeatCount() + 1);
                            InjectService.updateCommand(imei, entry.getKey(), command);
                        }
                    }
                }
            }
        }
        mqHeartBeatMessage.setFailedCmdList(failSendList);
        //将redis中的重发失败的指令删除，下次不再重发
        if (failSendList.size() > 0) {
            for (String s : failSendList) {
                // PBWLALL不在这删除的原因是放到后面Manager服务去进行删除
                if (s.contains(Constants.ALL_WHITELIST_NUMBER)) {
                    continue;
                }
                InjectService.delCommand(imei, s);
            }
        }
        return imei;
    }
}
